package com.zhoug.zxing.utils;

import android.graphics.Bitmap;
import android.util.Log;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.NotFoundException;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.zhoug.zxing.decode.DecodeFormatManager;
import com.zhoug.zxing.decode.DecodeThread;

import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Map;

/**
 * 二维码/条形码解析器
 *
 * @Author 35574
 * @Date 2020/12/9
 * @Description
 */
public class ZxingDecoder {
    private static final String TAG = ">>>ZxingDecoder";
    private MultiFormatReader mMultiFormatReader;


    /**
     * 创建条形码/二维码解析器
     *
     * @param decodeMode 解析模式
     *                   {@link DecodeThread#ALL_MODE}所有模式
     *                   {@link DecodeThread#BARCODE_MODE} 条形码
     *                   {@link DecodeThread#QRCODE_MODE} 二维码
     * @return
     */
    public ZxingDecoder(int decodeMode) {
        mMultiFormatReader = createMultiFormatReader(decodeMode);
    }

    public ZxingDecoder() {
        this(DecodeThread.ALL_MODE);
    }

    /**
     * 创建条形码/二维码解析器
     *
     * @param decodeMode 解析模式
     *                   {@link DecodeThread#ALL_MODE}所有模式
     *                   {@link DecodeThread#BARCODE_MODE} 条形码
     *                   {@link DecodeThread#QRCODE_MODE} 二维码
     * @return
     */
    private MultiFormatReader createMultiFormatReader(int decodeMode) {
        Map<DecodeHintType, Object> hints = new EnumMap<DecodeHintType, Object>(DecodeHintType.class);
        Collection<BarcodeFormat> decodeFormats = new ArrayList<BarcodeFormat>();
        decodeFormats.addAll(EnumSet.of(BarcodeFormat.AZTEC));
        decodeFormats.addAll(EnumSet.of(BarcodeFormat.PDF_417));
        switch (decodeMode) {
            case DecodeThread.BARCODE_MODE:
                decodeFormats.addAll(DecodeFormatManager.getBarCodeFormats());
                break;

            case DecodeThread.QRCODE_MODE:
                decodeFormats.addAll(DecodeFormatManager.getQrCodeFormats());
                break;

            case DecodeThread.ALL_MODE:
                decodeFormats.addAll(DecodeFormatManager.getBarCodeFormats());
                decodeFormats.addAll(DecodeFormatManager.getQrCodeFormats());
                break;
            default:
                break;
        }
        hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
        MultiFormatReader multiFormatReader = new MultiFormatReader();
        multiFormatReader.setHints(hints);
        return multiFormatReader;
    }


    /**
     * 识别图片中的二维码/条形码
     *
     * @param bitmap
     * @return {@link Result#getText()} 识别结果
     */
    public Result decode(Bitmap bitmap) {
        if (bitmap == null) {
            Log.e(TAG, "bitmap is null");
            return null;
        }
        int[] pixels = new int[bitmap.getWidth() * bitmap.getHeight()];
        bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
        RGBLuminanceSource source = new RGBLuminanceSource(bitmap.getWidth(), bitmap.getHeight(), pixels);
        BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));
        Result result = null;
        try {
            result = mMultiFormatReader.decode(binaryBitmap);
        } catch (NotFoundException e) {
            Log.e(TAG, "识别失败"+e.getMessage());
            e.printStackTrace();
        } finally {
            mMultiFormatReader.reset();
        }
        return result;
    }

    /**
     * 识别图片中的二维码/条形码
     *
     * @param path
     * @return
     */
    public Result decode(String path) {
        Bitmap bitmap = Utils.decodeFile(path, 720, 1080, Bitmap.Config.ARGB_8888);
//        Bitmap bitmap = Utils.decodeFile(path,1,Bitmap.Config.ARGB_8888);
        return decode(bitmap);
    }



    public static String parseResult(Result result) {
        if (result != null) {
            return result.getText();
        }
        return null;
    }



}
